﻿namespace Ruirun.Mes
{
    public partial class MesService
    {
        /// <summary>
        /// 获取 实体仓储对象
        /// </summary>
        private MaterialOutStorageStore MaterialOutStorageStore => ServiceProvider.GetService<MaterialOutStorageStore>();

        /// <summary>
        /// 获取 实体查询数据集
        /// </summary>
        public IQueryable<MaterialOutStorage> MaterialOutStorages => MaterialOutStorageStore.Entities;

        /// <summary>
        /// 根据编号查找
        /// </summary>
        /// <param name="id">数据实体编号</param>
        /// <returns>业务操作结果</returns>
        public async Task<OperationResult<MaterialOutStorageOutputDto>> FindMaterialOutStorageById(Guid id)
        {
            Check.NotEmpty(id, nameof(id));

            var outputDto = MaterialOutStorages.Where(o => o.Id.Equals(id)).ToOutput<MaterialOutStorage, MaterialOutStorageOutputDto>().FirstOrDefault();
            if (outputDto != null)
            {
                return await Task.FromResult(new OperationResult<MaterialOutStorageOutputDto>(OperationResultType.Success, "OK", outputDto));
            }

            return await Task.FromResult(new OperationResult<MaterialOutStorageOutputDto>(OperationResultType.NotFound, "Not Found", outputDto));
        }

        /// <summary>
        /// 新增出库
        /// </summary>
        /// <param name="dto">DTO信息</param>
        /// <returns>业务操作结果</returns>
        public async Task<OperationResult> CreateMaterialOutStorage(MaterialOutStorageInputDto dto)
        {
            Check.NotNull(dto, nameof(dto));

            OperationResult operation = OperationResult.Error("操作尚未处理");
            #region step1:物料仓库信息            
            Material material = MaterialStore.Entities.FirstOrDefault(a => a.Id == dto.MaterialId);
            if (material == null) return OperationResult.Error("物料信息异常");

            #endregion

            #region step2:新增入库记录
            if (dto.Num > material.Num) return OperationResult.Error($"IPN:{material.IPN},当前库位库存不足");

            MaterialOutStorage outStorage = new MaterialOutStorage
            {
                MaterialId = material.Id,
                Project = dto.Project,
                Num = dto.Num,
                UseTarget = dto.UseTarget,
                Remark = dto.Remark,
                Status = OutStorgeStatus.Apply,
            };
            operation = await MaterialOutStorageStore.InsertAsync(outStorage);
            if (operation.Failed) return operation;

            #endregion

            #region step4:物料仓库数量处理
            material.Num -= outStorage.Num;
            operation = await MaterialStore.UpdateAsync(material);

            #endregion

            return operation;
        }

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="dtos">DTO信息</param>
        /// <returns>业务操作结果</returns>
        public async Task<OperationResult> UpdateMaterialOutStorages(params MaterialOutStorageInputDto[] dtos)
        {
            return await MaterialOutStorageStore.UpdateByDtoAsync(dtos);
        }

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="id">数据实体编号</param>
        /// <returns>业务操作结果</returns>
        public async Task<OperationResult> DeleteMaterialOutStorage(Guid id)
        {
            OperationResult operation = OperationResult.Error("撤销失败");
            var outstorage = MaterialOutStorageStore.Entities.FirstOrDefault(a => a.Id == id);
            Check.NotNull(outstorage, nameof(outstorage));

            var material = MaterialStore.Entities.FirstOrDefault(a => a.Id == outstorage.MaterialId);
            Check.NotNull(material, nameof(material));
            //if (material.Num < material.Num) return OperationResult.Error("库存不足，撤销失败");

            material.Num += outstorage.Num;
            operation = MaterialStore.Update(material);
            //if (material.Num > 0)
            //{
            //    operation = MaterialStore.Update(material);
            //}
            //else
            //{
            //    operation = MaterialStore.Delete(material);
            //}

            if (operation.Succeeded)
            {
                operation = MaterialOutStorageStore.Delete(outstorage);
            }
            return operation;
        }

        /// <summary>
        /// 审批操作
        /// </summary>
        public async Task<OperationResult> ApplyOutStorageHandler(Guid id, OutStorgeStatus target)
        {
            OperationResult operation = OperationResult.Error("操作失败");

            var outStorage = MaterialOutStorageStore.Entities.FirstOrDefault(a => a.Id == id);
            if (outStorage == null) return OperationResult.Error("当前出库单不存在");

            if (outStorage.Status == OutStorgeStatus.Complete) return OperationResult.Error("当前单据已完成，无法执行其它操作");

            switch (target)
            {
                case OutStorgeStatus.Apply:
                    if (outStorage.Status != OutStorgeStatus.RdApprove) return OperationResult.Error("单据状态不符当前操作");
                    outStorage.Status = target;
                    break;
                case OutStorgeStatus.RdApprove:
                    if (outStorage.Status != OutStorgeStatus.Apply) return OperationResult.Error("单据状态不符当前操作");
                    outStorage.Status = target;
                    break;
                case OutStorgeStatus.Complete:
                    if (outStorage.Status != OutStorgeStatus.RdApprove) return OperationResult.Error("单据状态不符当前操作");
                    outStorage.Status = target;
                    break;
                default:
                    break;
            }
            operation = await MaterialOutStorageStore.UpdateAsync(outStorage);
            return operation;

        }

    }
}